/**
 * Copyright 2024-2024 Huawei Technologies Co., Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef FRAMEWORK_C_DDK_MODEL_MANAGER_HIAI_BUILT_MODEL_H
#define FRAMEWORK_C_DDK_MODEL_MANAGER_HIAI_BUILT_MODEL_H

#include <stddef.h>

#include "c/hiai_c_api_export.h"
#include "c/hiai_error_types.h"
#include "c/hcl/hiai_types.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief 恢复编译后模型。
 *
 * 用于将保存的模型数据在设备上重新载入，生成编译后模型{@link HIAI_MR_BuiltModel}指针实例。
 * {@link HIAI_MR_BuiltModel}不使用时，使用{@link HIAI_MR_BuiltModel_Destroy}进行释放，否则将造成内存泄漏。
 * 模型数据data在HIAI_MR_BuiltModel_Restore之后不能立即释放，在HIAI_MR_ModelManager_Init之后才可以释放
 *
 * @param [in] data 模型的数据地址，非空，否则返回失败
 * @param [in] size 模型的数据大小，大于0，否则返回失败
 * @return 函数执行结果。执行成功返回{@link HIAI_MR_BuiltModel}的指针实例；失败返回空指针
 * @see HIAI_MR_BuiltModel_Destroy
 */
AICP_C_API_EXPORT HIAI_MR_BuiltModel* HIAI_MR_BuiltModel_Restore(const void* data, size_t size);

/**
 * @brief 恢复编译后模型文件。
 *
 * 用于将保存的模型文件在设备上重新载入，生成编译后模型{@link HIAI_MR_BuiltModel}指针实例。
 * {@link HIAI_MR_BuiltModel}不使用时，使用{@link HIAI_MR_BuiltModel_Destroy}进行释放，否则将造成内存泄漏。
 *
 * @param [in] path 传入的模型文件，使用绝对路径且进程有读权限，非空，否则返回失败
 * @return 函数执行结果。执行成功返回{@link HIAI_MR_BuiltModel}的指针实例；失败返回空指针
 * @see HIAI_MR_BuiltModel_Destroy
 */
AICP_C_API_EXPORT HIAI_MR_BuiltModel* HIAI_MR_BuiltModel_RestoreFromFile(const char* file);

/**
 * @brief 保存编译后的模型{@link HIAI_MR_BuiltModel}到指定的内存地址上。
 *
 * 此方法用于将通过{@link HIAI_MR_BuiltModel_Restore}、{@link HIAI_MR_BuiltModel_RestoreFromFile}或
 * {@link HIAI_MR_ModelBuilder_Build}生成的{@link HIAI_MR_BuiltModel}进行保存，保存到用户指定的内存地址上。
 * 内存由用户申请和释放，建议内存申请比模型大，在200M以内。
 *
 * @param [in] model {@link HIAI_MR_BuiltModel}指针实例，非空，否则返回失败
 * @param [in] data 用户申请的内存地址，非空，否则返回失败
 * @param [in] size 用户申请的内存地址的大小，大于0，需要大于等于待保存的模型大小，否则返回失败
 * @param [out] realSize 保存的模型数据的真实大小
 * @return 函数执行结果状态。执行成功返回HIAI_SUCCESS；失败返回具体错误码，具体失败错误码可参考{@link HIAI_Status}
 */
AICP_C_API_EXPORT HIAI_Status HIAI_MR_BuiltModel_SaveToExternalBuffer(
    const HIAI_MR_BuiltModel* model, void* data, size_t size, size_t* realSize);

/**
 * @brief 保存编译后的模型{@link HIAI_MR_BuiltModel}到指定文件。
 *
 * 此方法是用于将通过{@link HIAI_MR_BuiltModel_Restore}、{@link HIAI_MR_BuiltModel_RestoreFromFile}或
 * {@link HIAI_MR_ModelBuilder_Build}生成的{@link HIAI_MR_BuiltModel}进行保存，保存到用户提供的文件上。
 * 用户提供的文件，需确保用户进程对其有写权限，建议提供绝对路径及文件名
 *
 * @param [in] model {@link HIAI_MR_BuiltModel}指针实例，非空，否则返回失败
 * @param [in] file 用户指定的文件，使用全路径且进程有写权限，非空，否则返回失败
 * @return 函数执行结果状态。执行成功返回HIAI_SUCCESS；失败返回具体错误码，具体失败错误码可参考{@link HIAI_Status}
 */
AICP_C_API_EXPORT HIAI_Status HIAI_MR_BuiltModel_SaveToFile(const HIAI_MR_BuiltModel* model, const char* file);

/**
 * @brief 查询模型的名称。
 *
 * @param [in] model {@link HIAI_MR_BuiltModel}指针实例，非空，否则返回失败
 * @return 函数执行结果。成功时返回模型名称，失败返回空指针
 */
AICP_C_API_EXPORT const char* HIAI_MR_BuiltModel_GetName(const HIAI_MR_BuiltModel* model);

/**
 * @brief 设置模型的名称。
 *
 * @param [in] model {@link HIAI_MR_BuiltModel}指针实例，非空，否则返回失败
 * @param [in] name 模型名称，非空，长度小于128个字符，否则返回失败
 * @return 函数执行结果状态。执行成功返回HIAI_SUCCESS；失败返回具体错误码，具体失败错误码可参考{@link HIAI_Status}
 */
AICP_C_API_EXPORT HIAI_Status HIAI_MR_BuiltModel_SetName(const HIAI_MR_BuiltModel* model, const char* name);

/**
 * @brief 查询模型输入的数量。
 *
 * @param [in] model {@link HIAI_MR_BuiltModel}指针实例，非空，否则返回失败
 * @return 函数执行结果。成功时返回模型中输入的节点数量，失败时返回0
 */
AICP_C_API_EXPORT int32_t HIAI_MR_BuiltModel_GetInputTensorNum(const HIAI_MR_BuiltModel* model);

/**
 * @brief 获取指定索引的模型输入的描述。
 *
 * 用于获取编译后模型的某个输入的描述，索引计数从0开始。
 * {@link HIAI_NDTensorDesc}指针实例不再使用时，需调用{@link HIAI_NDTensorDesc_Destroy}进行销毁，否则将造成内存泄漏。
 *
 * @param [in] model {@link HIAI_MR_BuiltModel}指针实例，非空，否则返回失败
 * @param [in] index 模型某一个输入的索引，大于等于0，小于模型输入的数量，否则返回失败
 * @return 函数执行结果。成功时返回对应输入的描述{@link HIAI_NDTensorDesc}指针实例，失败时返回空指针
 * @see  HIAI_NDTensorDesc_Destroy
 */
AICP_C_API_EXPORT HIAI_NDTensorDesc* HIAI_MR_BuiltModel_GetInputTensorDesc(
    const HIAI_MR_BuiltModel* model, size_t index);

/**
 * @brief 获取指定索引的模型输入的名称。
 *
 * 用于获取编译后模型的某个输入的名称，索引计数从0开始。
 *
 * @param [in] model {@link HIAI_MR_BuiltModel}指针实例，非空，否则返回失败
 * @param [in] index 模型某一个输入的索引，大于等于0，小于模型输入的数量，否则返回失败
 * @param [in] tensorName 用户申请的模型输入名称的头指针地址，用于接收返回的输入名称，非空，否则返回失败
 * @param [in] nameLen 模型输入名称的长度，应大于等于待获取名称的长度+1
 * @return 函数执行结果状态。执行成功返回HIAI_SUCCESS；失败返回具体错误码，具体失败错误码可参考{@link HIAI_Status}
 */
AICP_C_API_EXPORT HIAI_Status HIAI_MR_BuiltModel_GetInputTensorName(const HIAI_MR_BuiltModel* model, size_t index,
    char* tensorName, size_t nameLen);

/**
 * @brief 查询模型输出的数量。
 *
 * @param [in] model {@link HIAI_MR_BuiltModel}指针实例，非空，否则返回失败
 * @return 函数执行结果。成功时返回模型输出的节点数量，失败时返回0
 */
AICP_C_API_EXPORT int32_t HIAI_MR_BuiltModel_GetOutputTensorNum(const HIAI_MR_BuiltModel* model);

/**
 * @brief 获取指定索引的模型输出的描述。
 *
 * 用于获取编译后模型的某个输出的描述，索引计数从0开始。
 * {@link HIAI_NDTensorDesc}指针实例不再使用时，需调用{@link HIAI_NDTensorDesc_Destroy}进行销毁，否则将造成内存泄漏。
 *
 * @param [in] model {@link HIAI_MR_BuiltModel}指针实例，非空，否则返回失败
 * @param [in] index 模型某一个输出的索引，大于等于0，小于模型输出的数量，否则返回失败
 * @return 函数执行结果。成功时返回对应输出的描述{@link HIAI_NDTensorDesc}指针实例，失败时返回空指针
 * @see  HIAI_NDTensorDesc_Destroy
 */
AICP_C_API_EXPORT HIAI_NDTensorDesc* HIAI_MR_BuiltModel_GetOutputTensorDesc(
    const HIAI_MR_BuiltModel* model, size_t index);

/**
 * @brief 获取指定索引的模型输出的名称。
 *
 * 用于获取编译后模型的某个输出的名称，索引计数从0开始。
 *
 * @param [in] model {@link HIAI_MR_BuiltModel}指针实例，非空，否则返回失败
 * @param [in] index 模型某一个输出的索引，大于等于0，小于模型输出的数量，否则返回失败
 * @param [in] tensorName 用户申请的模型输出名称的头指针地址，用于接收返回的输出名称，非空，否则返回失败
 * @param [in] nameLen 模型输出名称对应的长度，应大于等于待获取名称的长度+1
 * @return 函数执行结果状态。执行成功返回HIAI_SUCCESS；失败返回具体错误码，具体失败错误码可参考{@link HIAI_Status}
 */
AICP_C_API_EXPORT HIAI_Status HIAI_MR_BuiltModel_GetOutputTensorName(const HIAI_MR_BuiltModel* model, size_t index,
    char* tensorName, size_t nameLen);

/**
 * @brief 销毁编译后模型的指针实例
 *
 * 用于销毁{@link HIAI_MR_BuiltModel_Restore}、{@link HIAI_MR_BuiltModel_RestoreFromFile}或{@link HIAI_MR_ModelBuilder_Build}构造出的
 * {@link HIAI_MR_BuiltModel}指针实例，传入指针的引用即可。若不调用，将造成内存泄漏。
 *
 * @param [in] model {@link HIAI_MR_BuiltModel}指针实例的引用，非空。
 */
AICP_C_API_EXPORT void HIAI_MR_BuiltModel_Destroy(HIAI_MR_BuiltModel** model);

#ifdef __cplusplus
}
#endif

#endif // FRAMEWORK_C_DDK_MODEL_MANAGER_HIAI_BUILT_MODEL_H
